package felix.things.router.mqtt.listener;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.util.StringUtils;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;

import java.nio.charset.StandardCharsets;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Felix
 * @date 2019/7/27
 **/
@Slf4j
public abstract class BaseRpcMessageListener implements IMqttMessageListener {

    /**
     * 处理rpc请求
     *
     * @param deviceName 设备名
     * @param methodName 请求类型
     * @param data       请求数据
     */
    protected abstract ListenableFuture<String> processingRpc(String deviceName, String methodName, String data);

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) {
        String data = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8);
        log.debug("topic: 【{}】 ,data 【{}】", toString(), data);
        String methodName = regexGetMatcher("(?<=request/)(.*?)(?=/\\d)", topic);
        String deviceName = regexGetMatcher("(?<=sensor/)(.*?)(?=/request)", topic);
        String requestId = regexGetMatcher("(?<=/)[0-9]\\d*$", topic);
        if (StringUtils.isEmpty(methodName) || StringUtils.isEmpty(deviceName) || StringUtils.isEmpty(requestId)) {
            log.error("【{}】未解析到关键数据", topic);
        } else {
            log.info("开始处理rpc请求 methodName:【{}】,deviceName:【{}】,requestId【{}】", methodName, deviceName, requestId);
            processingRpc(deviceName, methodName, data)
                    .addCallback(new ListenableFutureCallback<String>() {
                        @Override
                        public void onFailure(Throwable throwable) {
                            log.error("rpc执行失败", throwable);
                        }

                        @Override
                        public void onSuccess(String aVoid) {
                            // 回复rpc请求
                        }
                    });
        }
    }

    /**
     * 获取第一个正则取到的值
     *
     * @param regex
     * @param data
     * @return
     */
    private String regexGetMatcher(String regex, String data) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(data);
        if (m.find()) {
            return m.group();
        }
        return null;
    }

}
